package com.xxm.camera.camerax

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.graphics.Color
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CameraMetadata.LENS_FACING_BACK
import android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT
import android.os.Environment
import android.util.Log
import android.view.Gravity
import android.view.OrientationEventListener
import android.view.Surface
import android.view.View.GONE
import android.view.WindowManager.LayoutParams
import android.widget.LinearLayout
import android.widget.Toast
import androidx.camera.camera2.interop.Camera2CameraInfo
import androidx.camera.camera2.interop.ExperimentalCamera2Interop
import androidx.camera.core.*
import androidx.camera.core.ImageCapture.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import com.google.common.util.concurrent.ListenableFuture
import com.xxm.R
import com.xxm.databinding.ActivityCameraxBinding
import com.zhangws.comman.base.BaseActivity
import com.zhangws.comman.util.ResourceUtils
import java.io.File
import java.util.concurrent.Executors

@ExperimentalCamera2Interop
/**
 *Time:2023/6/8
 *Author:zhangwenshuan
 *Description:
 *since version
 * CameraX 预览，编解码保存本地 cameraX无法同时预览多个摄像头
 *
 */
class CameraXActivity : BaseActivity<ActivityCameraxBinding>() {
    private val TAG = "CameraXActivity"
    private val PERMISSION_REQUEST_CODE: Int = 1

    private val permissions = listOf(
        Manifest.permission.CAMERA,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    )

    private var cameraFuture: ListenableFuture<ProcessCameraProvider>? = null
    private var cameraProvider: ProcessCameraProvider? = null
    private var cameraPreview: Preview? = null

    private var cameraInfoList = mutableListOf<CameraInfo>()


    private var imageCaptures = mutableListOf<ImageCapture>()

    private val previewWidth by lazy {
        resources.displayMetrics.widthPixels / 3
    }


    override fun getViewDataBinding(): ActivityCameraxBinding = DataBindingUtil.setContentView(this, R.layout.activity_camerax)


    override fun initView() {
        if (checkPermissions()) {
            startCamera()
        }

        viewBinding.btnCapture.setOnClickListener {
            val outputFileOptions = ImageCapture.OutputFileOptions.Builder(
                File(
                    "/sdcard/DCIM",
                    "${System.currentTimeMillis()}.png"
                )
            ).build()
//            imageCapture?.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this), object : OnImageSavedCallback {
//
//
//                override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
//                    Log.d(TAG, "拍照成功")
//                    viewBinding.ivCapture.setImageURI(outputFileResults.savedUri)
//                }
//
//                override fun onError(exception: ImageCaptureException) {
//
//                    exception.printStackTrace()
//                    Log.e(TAG, "异常：${exception.message}")
//                }
//            })
        }
    }

    private fun initNotCameraView() {
        viewBinding.tvInfo.text = getString(R.string.not_camera)
        viewBinding.tvInfo.setTextColor(Color.RED)
        viewBinding.tvInfo.gravity = Gravity.CENTER
        viewBinding.tvInfo.textSize = ResourceUtils.spToPixel(20f)
        viewBinding.nsvOptions.visibility = GONE
    }

    private fun isSupportCamera(): Boolean {
        val cameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
        if (cameraManager.cameraIdList.isEmpty()) return false

        var info = ""
        cameraManager.cameraIdList.forEach {
            info = "摄像头ID:${it}\n${info}"
        }

        viewBinding.tvInfo.text = info
        return true
    }

    private fun startCamera() {
        cameraFuture = ProcessCameraProvider.getInstance(this)
        cameraProvider = cameraFuture?.get()

        val cameraInfos = cameraProvider?.availableCameraInfos

        if (cameraInfos == null || cameraInfos.isEmpty()) {
            runOnUiThread {
                initNotCameraView()
            }
            return
        } else {
            cameraInfoList.clear()
            cameraInfoList.addAll(cameraInfos)
            runOnUiThread {
                var info = ""
                cameraInfos.forEachIndexed { index, it ->
                    info = "CameraInfo${index},lensFacing:${it.lensFacing}," +
                            "exposure support:${it.exposureState.isExposureCompensationSupported}," +
                            "range:${it.exposureState.exposureCompensationRange},step${it.exposureState.exposureCompensationStep}、index:${it.exposureState.exposureCompensationIndex}\n" +
                            "intrinsicZoomRatio:${it.intrinsicZoomRatio},zoomState:${it.zoomState.value?.zoomRatio},range${it.zoomState.value?.minZoomRatio}-${it.zoomState.value?.maxZoomRatio}\n" +
                            "torchState:${it.torchState.value}\n" +
                            "level:${Camera2CameraInfo.from(it).getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)}\n" +
                            "rotationDegrees:${it.sensorRotationDegrees}\n"
                }
                setInfo(info)
                viewBinding.tvInfo.gravity = Gravity.TOP.or(Gravity.LEFT)
            }
        }
        val mainExecutors = ContextCompat.getMainExecutor(this)

        cameraInfos.forEach {
            createPreview()
        }

        cameraFuture?.addListener(object : Runnable {
            override fun run() {

                val previews= mutableListOf<Preview>()

                val builder=CameraSelector.Builder()
                cameraInfos.forEachIndexed { index, cameraInfo ->
                    cameraPreview = Preview.Builder().build().also {
                        it.setSurfaceProvider((viewBinding.llCameraPreview.getChildAt(index) as PreviewView).surfaceProvider)
                    }

                    previews.add(cameraPreview!!)
                    //builder.requireLensFacing(cameraInfo.lensFacing)
                }

                    val cameraSelector =builder
                        .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                        .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
                        .build()

                    val imageCapture = ImageCapture.Builder().build()

                    imageCaptures.add(imageCapture)
                    Log.d(TAG, "${cameraPreview.toString()}")
                    Log.d(TAG, "${cameraSelector.toString()}")
                    Log.d(TAG, "${previews.size}")
                    try {
                        cameraProvider?.bindToLifecycle(this@CameraXActivity,
                            cameraSelector,*previews.toTypedArray()
                        )
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Log.e(TAG, "${e.message}")
                    }
                }

        }, mainExecutors)
    }

    private fun createPreview(): PreviewView {

        val preview = PreviewView(this)
        val layoutParams = LinearLayout.LayoutParams(previewWidth, LayoutParams.MATCH_PARENT)
        viewBinding.llCameraPreview.addView(preview, layoutParams)

        return preview
    }

    private fun checkPermissions(): Boolean {
        var needRequest = false
        permissions.forEach {
            if (checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED) {
                needRequest = true
            }
        }
        if (needRequest) {
            requestPermissions(permissions.toTypedArray(), PERMISSION_REQUEST_CODE)
            return false
        }

        return true
    }

    override fun initListener() {

    }

    override fun initData() {

    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == PERMISSION_REQUEST_CODE) {
            grantResults.forEach {
                if (it == PackageManager.PERMISSION_DENIED) {
                    Toast.makeText(this, "需要授权", Toast.LENGTH_SHORT).show()
                }
            }

            if (checkPermissions()) {
                startCamera()
            }
        }
    }


    private fun setInfo(text: String) {
        viewBinding.tvInfo.text = "${text}\n${viewBinding.tvInfo.text}"
    }

    var rotation = 0;

    override fun onDestroy() {
        super.onDestroy()
        cameraProvider?.unbindAll()
    }

}